package com.wodan.zhongjinjicang.common.orm.command.write;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.ibatis.mapping.SqlCommandType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wodan.zhongjinjicang.common.orm.RdsCommonWriteDao;
import com.wodan.zhongjinjicang.common.orm.command.base.AbstractSqlCommandExecutor;
import com.wodan.zhongjinjicang.common.orm.metadata.MethodMetaData;
import com.wodan.zhongjinjicang.common.orm.metadata.TableMetaData;
import com.wodan.zhongjinjicang.common.orm.utils.ReflectionUtils;
import com.wodan.zhongjinjicang.common.orm.utils.SqlGenernateUtils;

/**
 * 插入操作的执行者
 * 
 * @ClassName: SqlInsertExecutor
 * @author Administrator
 * @date 2015-11-5 下午4:43:12
 * @history
 * 
 */
public class SqlBatchInsertExecutor extends AbstractSqlCommandExecutor {
	private static final Logger LOGGER = LoggerFactory.getLogger(SqlBatchInsertExecutor.class);
	
	@Override
	protected Object doExecute(final TableMetaData tableMetaData, MethodMetaData methodMetaData,
			final Object[] args) {
		Assert.notEmpty(args);
		Assert.isTrue(args.length == 1);

		Map<String, List<Object[]>> batchSqlMap = Maps.newHashMap();
		final List<?> entityList = (List<?>) args[0];
		for (Object entity : entityList) {
			// 解析bean内容为数据库的字段内容
			Map<String, Object> fieldValueMap = resolveBeanToColumnNameMap(entity, tableMetaData);
			final String tableName = tableMetaData.getTableName();
			final String[] columnNames = fieldValueMap.keySet().toArray(new String[fieldValueMap.size()]);
			final Object[] values = fieldValueMap.values().toArray(new Object[fieldValueMap.size()]);

			// 生成sql语句插入数据库
			final String insertSql = super.createCachedSqlScript(new Callable<String>() {
				@Override
				public String call() throws Exception {
					return SqlGenernateUtils.createInsertSql(tableName, columnNames);
				}
			}, tableName, columnNames);

			LOGGER.debug("execute sql: [{}]", insertSql);

			List<Object[]> valuesList = batchSqlMap.get(insertSql);
			if (valuesList == null) {
				valuesList = Lists.newArrayList();
				batchSqlMap.put(insertSql, valuesList);
			}
			valuesList.add(values);
		}

		// 批量插入数据库
		List<Integer> resultList = Lists.newArrayList();
		for (Map.Entry<String, List<Object[]>> entry : batchSqlMap.entrySet()) {
			int[] resultArray = jdbcTemplate.batchUpdate(entry.getKey(), entry.getValue());
			for (int result : resultArray) {
				resultList.add(Integer.valueOf(result));
			}
		}
		
		return resultList.toArray(new Integer[resultList.size()]);
	}

	@Override
	public Method getProxyMethod() {
		return ReflectionUtils.findMethod(RdsCommonWriteDao.class, "batchInsert", List.class);
	}

	@Override
	public SqlCommandType getSqlCommandType() {
		return SqlCommandType.INSERT;
	}
}
